#ifndef _DRV8301_H_
#define _DRV8301_H_


/* Includes -------------------------------------------------------------*/
#ifdef MATLAB_MEX_FILE
#include "tmwtypes.h"
#else
#include "rtwtypes.h"
#include "DSP28x_Project.h"
#endif


/* Defines --------------------------------------------------------------*/
/* REGISTER ADDRESS */
#define DRV8301_STATUS1_REG							0x00
#define DRV8301_STATUS1_REG_FAULT_BIT				(0x1 << 10)
#define DRV8301_STATUS1_REG_GVDD_UV_BIT				(0x1 << 9)
#define DRV8301_STATUS1_REG_PVDD_UV_BIT				(0x1 << 8)
#define DRV8301_STATUS1_REG_OTSD_BIT				(0x1 << 7)
#define DRV8301_STATUS1_REG_OTW_BIT					(0x1 << 6)
#define DRV8301_STATUS1_REG_FETHA_OC_BIT			(0x1 << 5)
#define DRV8301_STATUS1_REG_FETLA_OC_BIT			(0x1 << 4)
#define DRV8301_STATUS1_REG_FETHB_OC_BIT			(0x1 << 3)
#define DRV8301_STATUS1_REG_FETLB_OC_BIT			(0x1 << 2)
#define DRV8301_STATUS1_REG_FETHC_OC_BIT			(0x1 << 1)
#define DRV8301_STATUS1_REG_FETLC_OC_BIT			(0x1 << 0)

#define DRV8301_STATUS2_REG							0x01
#define DRV8301_STATUS2_REG_GVDD_OV_BIT				(0x1 << 7)
#define DRV8301_STATUS2_REG_DEVICE_ID_BIT			(0xF << 0)

#define DRV8301_CONTROL1_REG						0x02
#define DRV8301_CONTROL1_REG_OC_ADC_SET_BIT			(0x1F << 6)
#define DRV8301_CONTROL1_REG_OCP_MODE_BIT			(0x3 << 4)
#define DRV8301_CONTROL1_REG_PWM_MODE_BIT			(0x1 << 3)
#define DRV8301_CONTROL1_REG_GATE_RESET_BIT			(0x1 << 2)
#define DRV8301_CONTROL1_REG_GATE_CURRENT_BIT		(0x3 << 0)

#define DRV8301_CONTROL2_REG						0x03
#define DRV8301_CONTROL2_REG						0x03

#define DRV8301_REG_ACCESS_WRITE					0
#define DRV8301_REG_ACCESS_READ						1

/* CONTROL REGISTER 1 - GATE_CURRENT */
#define DRV8301_GATE_CURRENT_1A7					0
#define DRV8301_GATE_CURRENT_0A7					1
#define DRV8301_GATE_CURRENT_0A25					2
#define DRV8301_GATE_CURRENT_RESERVED				3

/* CONTROL REGISTER 1 - GATE_RESET */
#define DRV8301_GATE_NORMAL							0
#define DRV8301_GATE_RESET							1

/* CONTROL REGISTER 1 - PWM_MODE */
#define DRV8301_PWM_MODE_6PWM						0
#define DRV8301_PWM_MODE_3PWM						1

/* CONTROL REGISTER 1 - OCP_MODE */
#define DRV8301_OCP_CURRENT_LIMIT					0
#define DRV8301_OCP_LATCH_SHUTDOWN					1
#define	DRV8301_OCP_REPORT_ONLY						2
#define DRV8301_OCP_DISABLED						3

/* CONTROL REGISTER 1 - OC_ADJ_SET */
#define DRV8301_OCADJ_0_060							0		// Vds = 0.060V
#define DRV8301_OCADJ_0_068							1		// Vds = 0.068V
#define DRV8301_OCADJ_0_076							2		// Vds = 0.076V
#define DRV8301_OCADJ_0_086							3		// Vds = 0.086V
#define DRV8301_OCADJ_0_097							4		// Vds = 0.097V
#define DRV8301_OCADJ_0_109							5		// Vds = 0.109V
#define DRV8301_OCADJ_0_123							6		// Vds = 0.123V
#define DRV8301_OCADJ_0_138							7		// Vds = 0.138V
#define DRV8301_OCADJ_0_155							8		// Vds = 0.155V
#define DRV8301_OCADJ_0_175							9		// Vds = 0.175V
#define DRV8301_OCADJ_0_197							10		// Vds = 0.197V
#define DRV8301_OCADJ_0_222							11		// Vds = 0.222V
#define DRV8301_OCADJ_0_250							12		// Vds = 0.250V
#define DRV8301_OCADJ_0_282							13		// Vds = 0.282V
#define DRV8301_OCADJ_0_317							14		// Vds = 0.317V
#define DRV8301_OCADJ_0_358							15		// Vds = 0.358V
#define DRV8301_OCADJ_0_403							16		// Vds = 0.403V
#define DRV8301_OCADJ_0_454							17		// Vds = 0.454V
#define DRV8301_OCADJ_0_511							18		// Vds = 0.511V
#define DRV8301_OCADJ_0_576							19		// Vds = 0.576V
#define DRV8301_OCADJ_0_648							20		// Vds = 0.648V
#define DRV8301_OCADJ_0_730							21		// Vds = 0.730V
#define DRV8301_OCADJ_0_822							22		// Vds = 0.822V
#define DRV8301_OCADJ_0_926							23		// Vds = 0.926V
#define DRV8301_OCADJ_1_043							24		// Vds = 1.043V
#define DRV8301_OCADJ_1_175							25		// Vds = 1.175V
#define DRV8301_OCADJ_1_324							26		// Vds = 1.324V
#define DRV8301_OCADJ_1_491							27		// Vds = 1.491V
#define DRV8301_OCADJ_1_679							28		// Vds = 1.679V
#define DRV8301_OCADJ_1_892							29		// Vds = 1.892V
#define DRV8301_OCADJ_2_131							30		// Vds = 2.131V
#define DRV8301_OCADJ_2_400							31		// Vds = 2.400V


/* CONTROL REGISTER 2 - OCTW_MODE */
#define DRV8301_OCTW_REPORT_OT_AND_OC				0
#define DRV8301_OCTW_REPORT_OT_ONLY					1
#define	DRV8301_OCTW_REPORT_OC_ONLY					2
#define DRV8301_OCTW_RESERVED						3

/* CONTROL REGISTER 2 - GAIN */
#define DRV8301_GAIN_10V_V							0
#define DRV8301_GAIN_20V_V							1
#define DRV8301_GAIN_40V_V							2
#define DRV8301_GAIN_80V_V							3

/* CONTROL REGISTER 2 - DC_CAL_CH1 & DC_CAL_CH2 */
#define DRV8301_DCCAL_LOAD_CONNECT					0
#define DRV8301_DCCAL_LOAD_DISCONNECT				1

/* CONTROL REGISTER 2 - OC_TOFF */
#define	DRV8301_OC_TOFF_CYCLE_BY_CYCLE				0
#define DRV8301_OC_TOFF_OFFTIME_CONTROL				1

#define DRV8301_DEFAULTS                            {			\
                                                    	0x0000,	\
                                                    	0x0000,	\
                                                    	0x0000,	\
                                                    	0x0000	\
                                                    }
                            
                            
#define Drv8301_EnableDcCal()						GpioDataRegs.GPBSET.bit.GPIO43 = 1
#define Drv8301_DisableDcCal()						GpioDataRegs.GPBCLEAR.bit.GPIO43 = 1

#define Drv8301_IsFaultDetected()					(GpioDataRegs.GPADAT.bit.GPIO14 == 0) ? 1 : 0
#define Drv8301_IsOctwDetected()					(GpioDataRegs.GPADAT.bit.GPIO13 == 0) ? 1 : 0

#define DRV8301_NOERROR     0x0000
#define DRV8301_RWFAIL      0x0001
#define DRV8301_OCTW        0x0002
#define DRV8301_FAULT       0x0003


/* Typedefs ------------------------------------------------------------------*/
typedef union
{
	uint16_T	all;
	struct
	{
		uint16_T	Data:11;
		uint16_T	Address:4;
		uint16_T	RWAccess:1;
	} bit;
} DATA_TX_T;


typedef union
{
	uint16_T	all;
	struct
	{
		uint16_T	Data:11;
		uint16_T	Address:4;
		uint16_T	Fault:1;
	} bit;
} DATA_RX_T;


typedef union
{
	uint16_T	all;
	struct
	{
		uint16_T	FETLC_OC:1;
		uint16_T	FETHC_OC:1;
		uint16_T	FETLB_OC:1;
		uint16_T	FETHB_OC:1;
		uint16_T	FETLA_OC:1;
		uint16_T	FETHA_OC:1;
		uint16_T	OTW:1;
		uint16_T	OTSD:1;
		uint16_T	PVDD_UV:1;
		uint16_T	GVDD_UV:1;
		uint16_T	FAULT:1;
		uint16_T	Reserved:5;
	} bit;
} STATUS1_REG;


typedef union
{
	uint16_T	all;
	struct
	{
		uint16_T	DeviceID:4;
		uint16_T	Reserved_1:3;
		uint16_T	GVDD_OV:1;
		uint16_T	Reserved_2:8;
	} bit;
} STATUS2_REG;


typedef union
{
	uint16_T	all;
	struct
	{
		uint16_T	GATE_CURRENT:2;
		uint16_T	GATE_RESET:1;
		uint16_T	PWM_MODE:1;
		uint16_T	OCP_MODE:2;
		uint16_T	OC_ADJ_SET:5;
		uint16_T	Reserved:5;
	} bit;
} CONTROL1_REG;


typedef union
{
	uint16_T	all;
	struct
	{
		uint16_T	OCTW_MODE:2;
		uint16_T	GAIN:2;
		uint16_T	DC_CAL_CH1:1;
		uint16_T	DC_CAL_CH2:1;
		uint16_T	OC_TOFF:1;
		uint16_T	Reserved:9;
	} bit;
} CONTROL2_REG;


typedef struct _DRV8301_
{
	STATUS1_REG     Stat1Reg;
	STATUS2_REG     Stat2Reg;
	CONTROL1_REG    Ctrl1Reg;
	CONTROL2_REG	Ctrl2Reg;
} DRV8301_OBJ;


/* Export functions -----------------------------------------------------*/
void Drv8301_Init(void);
void Drv8301_EnableGate(void);
void Drv8301_DisableGate(void);
void Drv8301_FaultReset(void);
void Drv8301_FullReset(void);
uint16_T Drv8301_WriteRegister(uint16_T Register, uint16_T Value);
uint16_T Drv8301_ReadRegister(uint16_T Register, uint16_T* Value);
uint16_T Drv8301_Config(uint16_T* IsenseU_Offset, uint16_T* IsenseV_Offset);
uint16_T Drv8301_CheckFault(void);

#endif /* _DRV8301_H_ */
